import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;

public class Stone extends JLabel implements Runnable {

	/**
	 * 
	 */
	public static final byte STAT_FALL_DOWN = -128;
	public static final byte STAT_WAIT_UNTIL_INTERRUPT = -127;
	public static final byte STAT_SHINE = -126;
	public static final byte STAT_DIE = -125;

	private static final long serialVersionUID = 1L;

	private static Icon[][] icons;
	private Thread thread;

	private final MousePanel mousepanel;
	private final Game game;
	private final GameFrame frame;
	private final byte fieldToMoveDown;
	private final Player player;
	private byte stat;

	public Stone(MousePanel mousePanel, Game game, byte y, GameFrame frame) {

		this.mousepanel = mousePanel;
		this.game = game;
		this.frame = frame;
		this.player = game.getMomPlayer();
		this.setIcon(icons[0][player.getPlayerNumber() - 1]);
		fieldToMoveDown = y;
		// TODO Auto-generated constructor stub
	}
	
	public Stone(MousePanel mousePanel,Game game,byte y,GameFrame frame,Player player)
	{
		this.mousepanel = mousePanel;
		this.game = game;
		this.frame = frame;
		this.player = player;
		this.setIcon(icons[0][player.getPlayerNumber() - 1]);
		fieldToMoveDown = y;
	}
	
	public Stone()
	{
		this.mousepanel = null;
		this.game = null;
		this.frame = null;
		this.player = null;
		this.setIcon(icons[0][0]);
		fieldToMoveDown = 0;
	}

	private void shine() {
		boolean back = false;
		mousepanel.setListenerBlocked(true);
		for (byte b = 1; true; b++) {
			setIcon(icons[back ? b : 8 - b][player.getPlayerNumber() - 1]);
			if (b == 7) {
				back = back ? false : true;
				b = 0;
			}

			try {
				Thread.sleep(30L);
			} catch (InterruptedException e) {
			}
		}

	}

	private boolean checkWon() {
		boolean won = false;
		Player player = game.getMomPlayer();

		ArrayList<ArrayList<Stone>> rowList = new ArrayList<ArrayList<Stone>>();
		for (int y = 0; y < 6; y++) {
			for (int x = 0; x < 7; x++) {
				Stone stoneOnField = game.getStoneFromField(x, y);
				if (stoneOnField != null && stoneOnField.getPlayer() == player) {
					for (int b = 0; b < 8; b++) {
						rowList.add(CheckWon.check(x, y, player, b, new ArrayList<Stone>(), game));
					}
				}
			}
		}

		for (int i = 0, size = rowList.size(); i < size && !won; i++) {
			ArrayList<Stone> innerList = rowList.get(i);
			if (innerList.size() >= 4) {
				game.isWon();

				for (byte b = 0, innerSize = (byte) innerList.size(); b < innerSize; b++)
					innerList.get(b).setStat(STAT_SHINE);
				won = true;
				game.getMomPlayer().wins();
			}
		}
		return (won);
	}

	static {

		BufferedImage image = null;

		try {
			image = ImageIO.read(new File("img\\stones.png"));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("Datei nicht gefunden");
		}

		icons = new Icon[9][2];

		for (int i = 0; i < icons[0].length; i++) {
			for (int j = 0; j < icons.length; j++) {
				Icon icon = new ImageIcon(image.getSubimage(j * 50, i * 50, 50, 50));
				icons[j][i] = icon;
			}
		}

	}

	public void start() {
		thread = new Thread(this, "Stone");
		thread.start();
	}

	@Override
	public void run() {
		do {
			switch (stat) {
			case STAT_FALL_DOWN:
				fall();
				break;

			case STAT_WAIT_UNTIL_INTERRUPT:
				try {
					Thread.yield();
				} catch (Exception e) {
					// TODO: handle exception
				}
				break;

			case STAT_SHINE:
				shine();
				break;

			default:
				stat = STAT_FALL_DOWN;
				break;
			}

		} while (stat != STAT_DIE);
	}

	public Player getPlayer() {
		return player;
	}

	private void fall() {
		int targetFieldY = fieldToMoveDown * 50 + (fieldToMoveDown + 1) * 2;
		while (getY() < targetFieldY) {

			if (getY() + 5 <= targetFieldY) {
				setLocation(getX(), getY() + 5);
			} else {
				setLocation(getX(), targetFieldY);
			}
			try {
				Thread.sleep(game.getGameOptions().getSpeed());
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
			}
		}
		stat = STAT_WAIT_UNTIL_INTERRUPT;
		if (!checkWon()) {
			game.nextPlayer();
			mousepanel.setListenerBlocked(false);
		}
	}

	public void setStat(byte newStat) {
		stat = newStat;

		if (thread != null) {
			thread.interrupt();
		}
	}

}
